package com.liruo.enumconverter.core.converter;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;

public class IntStrToEnumConverterFactory implements ConverterFactory<String, Enum> {
    public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
        Class<?> enumClass = targetType;
        if(!enumClass.isEnum()){
            enumClass = targetType.getSuperclass();
            if(!enumClass.isEnum()){
                return null;
            }
        }
        return new IntStrToEnum(enumClass);
    }


    private static class IntStrToEnum<T extends Enum> implements Converter<String, T> {
        private final Class<T> enumType;

        public IntStrToEnum(Class<T> enumType) {
            this.enumType = enumType;
        }

        public T convert(String source) {
            T[] enumConstants = this.enumType.getEnumConstants();
            int parseInt;
            try {
                parseInt = Integer.parseInt(source);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("require Int string but provider " + source
                        + ", err="+ e.getMessage());
            }
            if(parseInt >= enumConstants.length){
                throw new IllegalArgumentException(this.enumType.getName()
                        + " only has "
                        + enumConstants.length
                        + " constants but parseInt=" + parseInt);
            }
            return enumConstants[parseInt];
        }
    }
}